package switchviz.core.scenario;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.log4j.Logger;

import switchviz.core.ResourceManager;
import switchviz.core.view.ViewLegend;
import switchviz.core.view.ViewStatePanel;
import switchviz.gui.component.PaddingPanel;
import switchviz.network.NetworkStatePanel;
import switchviz.recording.ReplayStatePanel;
import switchviz.util.FileOperations;

public class ScenarioStateDialog extends JFrame implements ActionListener, ChangeListener, WindowListener, ItemListener
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 3013339684882086821L;
	private static Logger logger  = Logger.getLogger(ScenarioStateDialog.class);
	private Scenario _zen = null;
	private ViewStatePanel _viewstate = null;
	private ScenarioDataModel _zenmodel = null;
	private NetworkStatePanel _netstate = null;
	private ReplayStatePanel _replaystate = null;
	private JButton _buttclose = null;
	private Timer _timer = null;
	
	public ScenarioStateDialog(Scenario zen)
	{
		_zen = zen;
		_zenmodel = _zen.getScenarioModel();
		initialize();
		this.setIconImage(ResourceManager.getInstance().getImageIconScenario().getImage());
		
		if (_zen.getReplay() == null)
			this._timer = new Timer(_zen.getScenarioModel().getTimeintervall(), this);
		else
			this._timer = new Timer(200, this);
		
		_timer.start();
		
		this.setTitle("State of " + _zen.getScenarioModel().getTitle());
		this.pack();
		this.setLocationRelativeTo(null);
		this.setVisible(true);
	}
	
	private void initialize()
	{
		PaddingPanel statecontainer = new PaddingPanel(); 
		statecontainer.setLayout(new BoxLayout(statecontainer, BoxLayout.PAGE_AXIS));
		statecontainer.setBorder(BorderFactory.createLoweredBevelBorder());
		
		if(_zen.getView() != null)
		{
			_viewstate = new ViewStatePanel();
			_viewstate.setViewName(_zen.getView().getDataModel().getName());
			_viewstate.setSlider(_zen.getScenarioModel().getRenderrate());
			_viewstate.addActionListener(this);
			_viewstate.addChangeListener(this);
			_viewstate.addItemListener(this);
			statecontainer.add(_viewstate);
		}
		
		if(_zen.getReplay() == null)
		{
			_netstate = new NetworkStatePanel(_zen.getSwitch().getSwitchDataModel());
			_netstate.setTimerIntervall(_zen.getScenarioModel().getTimeintervall());
			//_netstate.setSynchronicity(_zen.getScenarioModel().isProcessSynchron());
			_netstate.addActionListener(this);
			//_netstate.addItemListener(this);
			
			statecontainer.add(_netstate);
		}
		else
		{
			_replaystate = new ReplayStatePanel(_zen.getReplay(), _zen.getView());
			
			statecontainer.add(_replaystate);
		}
			
		_buttclose = new JButton("Close");
		_buttclose.setActionCommand(ResourceManager.getInstance().getActionCancel());
		_buttclose.addActionListener(this);
		

		
		
		
        JPanel buttonpanel = new JPanel();
        buttonpanel.setLayout(new BoxLayout(buttonpanel, BoxLayout.LINE_AXIS));
        buttonpanel.setBorder(BorderFactory.createLoweredBevelBorder());
        buttonpanel.add(Box.createHorizontalGlue());
        buttonpanel.add(_buttclose);
        
        this.setLayout(ResourceManager.getInstance().getBorderLayout());
        this.addWindowListener(this);
		this.add(statecontainer, BorderLayout.CENTER);
		this.add(buttonpanel, BorderLayout.SOUTH);
	}

	public void actionPerformed(ActionEvent evt) 
	{
		String command = evt.getActionCommand();
		if(ResourceManager.getInstance().getActionSaveView().equals(command))
		{
			try
			{
				_zen.getView().saveCurrentView();
			}
			catch(Exception e)
			{
				logger.error("Can't save current View! " + e.getMessage());
				e.printStackTrace();
			}
		}
		else if(ResourceManager.getInstance().getActionSaveViewAs().equals(command))
		{
			try
			{
				final JFileChooser fc = new JFileChooser(ResourceManager.getInstance().getViewFolder());
				fc.setFileFilter(FileOperations.getXMLFileFilter("View Configuration File"));
				int retval = fc.showDialog(this, "Save View File");
				if(retval == JFileChooser.APPROVE_OPTION)
					_zen.getView().saveCurrentViewAs(fc.getSelectedFile());
			}
			catch(Exception e)
			{
				logger.error("Can't save current View! " + e.getMessage());
				e.printStackTrace();
			}
		}
		else if(ResourceManager.getInstance().getActionTransfer().equals(command))
		{
			_zenmodel.setTimeintervall(_netstate.getTimerIntervall());
			_zen.updateScenarioModel(_zenmodel);
			_timer.setDelay(_zenmodel.getTimeintervall());
		}
		else if(ResourceManager.getInstance().getActionCancel().equals(command))
		{
			_zen.closeScene();
			this.setVisible(false);
		}
		else if(ResourceManager.getInstance().getActionNew().equals(command))
		{
			new ViewLegend(_zen.getView());
		}
		else
		{
			if (_zen.getReplay() == null)
				_netstate.updateNetworkState(_zen.getSwitch().getNetworkStatus());
			else
				_replaystate.updateState();
		}
	}

	public void stateChanged(ChangeEvent evt) 
	{
		_zenmodel.setRenderrate(((JSlider)evt.getSource()).getValue());
		_zen.updateScenarioModel(_zenmodel);
	}

	public void itemStateChanged(ItemEvent evt) 
	{
		_zen.getView().getDataModel().setDisplayNotConnected(((JCheckBox)evt.getSource()).isSelected());
	}
	
	public void windowClosed(WindowEvent evt) 
	{
		_timer.stop();
		_zen.closeScene();
	}
	
	public void windowClosing(WindowEvent evt) 
	{
		_timer.stop();
		_zen.closeScene();
	}
	
	public void windowActivated(WindowEvent arg0) {}
	public void windowDeactivated(WindowEvent arg0) {}
	public void windowDeiconified(WindowEvent arg0) {}
	public void windowIconified(WindowEvent arg0) {}
	public void windowOpened(WindowEvent arg0) {}
}
